home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / OpenGL / OPENGL2.EXE / _SETUP.1 / rb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-21  |  72.4 KB  |  2,288 lines

  1. #include <math.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6.  
  7. #include <windows.h>
  8. #include <GL/gl.h>
  9.  
  10. #include "resource.h"
  11.  
  12. #define RB_MSG_ERROR        0
  13. #define RB_MSG_WARNING      1
  14. #define RB_MSG_INFORMATION  2
  15.  
  16. static DWORD s_window_width  = 640;
  17. static DWORD s_window_height = 480;
  18. static BOOL  s_index_texture_extension = FALSE;
  19. static BOOL  s_lock_arrays_extension = FALSE;
  20.  
  21. typedef struct
  22. {
  23.     float st[2];
  24.     float rgb[3];
  25.     float xyz[3];
  26. } RBIVertex;
  27.  
  28. typedef struct 
  29. {
  30.     RBIVertex     *interleaved_array;
  31.     int            num_vertex_rows;
  32.     int            num_cols;
  33.     int            num_vertices;
  34.     int            verts_per_row;
  35.  
  36.     int            num_element_rows;
  37.     unsigned int **elements_array;
  38. } RBDrawElementsData;
  39.  
  40. RBDrawElementsData s_elements_data;
  41.  
  42. const float RED[]   = { 1.0F, 0.0F, 0.0F };
  43. const float GREEN[] = { 0.0F, 1.0F, 0.0F };
  44. const float BLUE[]  = { 0.0F, 0.0F, 1.0F };
  45.  
  46. const char *APPNAME = "OpenGL RasterBench 1.00";
  47. const char *CFGNAME = "rb.cfg";
  48. const char *LOGNAME = "rb.log";
  49.  
  50. HGLRC s_hglrc;
  51. HDC   s_hGLDC;
  52. HWND  s_hwndOpenGL;
  53. BOOL  s_config_specified_on_cmdline;
  54. BOOL  s_noprompt;
  55. BOOL  s_everything;
  56. BOOL  s_lock_arrys = FALSE;
  57.  
  58. HPALETTE s_hPalette = NULL;
  59. int      s_redIndex, s_greenIndex, s_blueIndex, s_clearIndex;
  60.  
  61. int  RBInit( HINSTANCE, int, LPSTR );
  62. void RBShutdown( void );
  63. void RBGo( HINSTANCE, int );
  64.  
  65. void RBSetupPalette( HDC hDC );
  66. int  RBCreateContext( HWND hWnd );
  67. void RBDestroyContext( HWND hWnd );
  68.  
  69. void RBInitDialog( HWND hDlg );
  70. void RBReadConfigFromDialog( HWND hDlg );
  71.  
  72. void RBConfigOpenGL( void );
  73. HWND RBCreateOpenGLWindow( HINSTANCE, int );
  74.  
  75. void RBSelectColorMode( HMENU hMenu, WPARAM wID, HWND hDlg );
  76. void RBSelectDepthFunc( HMENU hMenu, WPARAM wID );
  77. void RBSelectFogCurve( HMENU hMenu, WPARAM wID );
  78. void RBSelectTriangleSize( HMENU hMenu, WPARAM wID );
  79.  
  80. void RBSelectTextureEnvironment( HMENU hMenu, WPARAM wID );
  81. void RBSelectTextureFormat( HMENU hMenu, WPARAM wID );
  82. void RBSelectTextureHeight( HMENU hMenu, WPARAM wID );
  83. void RBSelectTextureWidth( HMENU hMenu, WPARAM wID );
  84. void RBSelectTextureOrientation( HMENU hMenu, WPARAM wID );
  85. void RBSelectTextureFilter( HMENU hMenu, WPARAM wID );
  86. void RBCreateTexture( void );
  87. void RBSelectZoom( HMENU hMenu, WPARAM wID );
  88.  
  89. void RBStoreConfigToDisk( void );
  90.  
  91. int  RBMenuItemIsChecked( HWND hWnd, WPARAM wID );
  92. void RBToggleMenuCheck( HMENU hMenu, WPARAM wID );
  93.  
  94. void RBDoTest( HWND hWnd );
  95. void RBDoHatTest( HWND hWnd );
  96. void RBDoHatStripTest( HWND hWnd );
  97. void RBDoHatDrawElementsTest( HWND hWnd );
  98. void RBDoClearTest( HWND hWnd );
  99.  
  100. void RBBuildData( HWND hWnd );
  101.  
  102. void RBLogDialog( HINSTANCE hInstance );
  103. void RBGenerateLog( const char *logfilename );
  104.  
  105. void RBHelp( void );
  106.  
  107. #define RB_CANCEL 0
  108. #define RB_OK     1
  109.  
  110. void RbMessage( int type, const char *msg );
  111.  
  112. typedef struct
  113. {
  114.     unsigned long triangles_rendered;
  115.     float         elapsed_time;
  116.     float         triangles_second;
  117.     float         mpixels_second;
  118.  
  119.     float         area_filled;
  120.     unsigned long num_screen_triangles;
  121. } RBStats_s;
  122.  
  123. typedef struct
  124. {
  125.     int    size;
  126.     
  127.     int    rgb_mode;
  128.     int    do_depth_test;
  129.     int    do_depth_writes;
  130.     GLenum depth_func;
  131.     int    depth_size;
  132.     float  depth_clear;
  133.     
  134.     int    do_fog;
  135.     int    do_cheap_fog;
  136.     GLenum fog_curve;
  137.     
  138.     int      do_dither;
  139.     unsigned triangle_size;
  140.     GLenum   draw_buffer;
  141.     
  142.     GLenum shade_model;
  143.     
  144.     int    do_texture;
  145.     int    random_texture;
  146.     GLenum perspective_correction;
  147.     GLenum texture_environment;
  148.     int    texture_width;
  149.     int    texture_height;
  150.     float  ftexture_width, ftexture_height;
  151.     int    texture_format;
  152.     int    texture_orientation;
  153.     float  texture_zoom;
  154.     GLenum texture_filter;
  155.     
  156.     int    texture_clamp_s, texture_clamp_t;
  157.     
  158.     int    primitive;
  159.     
  160.     int    iterations;
  161. } RBConfig_s;
  162.  
  163. RBConfig_s s_config =
  164. {
  165.     sizeof( s_config ),
  166.         
  167.         TRUE,         // rgb_mode
  168.         FALSE,        // do_depth_test
  169.         TRUE,         // do_depth_writes
  170.         GL_LEQUAL,    // depth_func
  171.         16,           // depth_size
  172.         1.0F,         // clear depth
  173.         
  174.         FALSE,        // do_fog
  175.         FALSE,        // do_cheap_fog
  176.         GL_LINEAR,    // fog_curve
  177.         
  178.         FALSE,            // do_dither
  179.         50,               // triangle_size
  180.         GL_FRONT,         // draw_buffer
  181.         
  182.         GL_SMOOTH,        // shade_model
  183.         
  184.         FALSE,            // do_texture
  185.         TRUE,             // random texture
  186.         GL_NICEST,        // perspective_correction
  187.         GL_DECAL,         // texture_environment
  188.         64, 64,           // texture_width and texture_height
  189.         64.0F, 64.0F,
  190.         0,                // texture_format
  191.         0,                // texture_orientation
  192.         1.0F,             // texture zoom
  193.         GL_NEAREST,         // texture_filter
  194.         
  195.         FALSE, FALSE,     // clamp_s, clamp_t
  196.         
  197.         IDM_TRIANGLES,    // primitive
  198.         
  199.         1                 // iterations
  200. };
  201.  
  202. RBStats_s  s_stats;
  203.  
  204. BOOL CALLBACK StatsDialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  205. BOOL CALLBACK DialogProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  206. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
  207.  
  208. BOOL s_done = FALSE;
  209.  
  210. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
  211. {
  212.     
  213.     /*
  214.     ** execute the configuration dialog box
  215.     */
  216.     while ( !s_done )
  217.     {
  218.         if ( RBInit( hInstance, nCmdShow, lpCmdLine ) )
  219.         {
  220.             RBGo( hInstance, nCmdShow );
  221.             if ( !s_noprompt )
  222.                 RBLogDialog( hInstance );
  223.             RBGenerateLog( LOGNAME );
  224.             
  225.             if ( s_noprompt ) 
  226.                 s_done = 1;
  227.         }
  228.         else
  229.         {
  230.             break;
  231.         }
  232.     }
  233.     
  234.     return 0;
  235. }
  236.  
  237. /*
  238. ** RBInit
  239. */
  240. int RBInit( HINSTANCE hInstance, int nCmdShow, LPSTR lpCmdLine )
  241. {
  242.     RBConfig_s cfg;
  243.  
  244.     if ( strstr( lpCmdLine, "/?" ) || ( strstr( lpCmdLine, "-?" ) ) )
  245.     {
  246.         RBHelp();
  247.         return FALSE;
  248.     }
  249.  
  250.     if ( !SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ) )
  251.     {
  252.         OutputDebugString( "Could not set priority class\n" );
  253.         return 0;
  254.     }
  255.     if ( !SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ) )
  256.     {
  257.         OutputDebugString( "Could not set thread priority\n" );
  258.         return 0;
  259.     }
  260.     
  261.     /*
  262.     ** set a default iteration count
  263.     */
  264.     s_config.iterations = 1;
  265.     
  266.     /*
  267.     ** see if we're not supposed to prompt
  268.     */
  269.     if ( strstr( lpCmdLine, "-noprompt" ) )
  270.     {
  271.         s_noprompt = 1;
  272.     }
  273.     
  274.     if ( strstr( lpCmdLine, "-everything" ) )
  275.     {
  276.         s_noprompt = 1;
  277.         s_everything = 1;
  278.     }
  279.  
  280.     /*
  281.     ** see if an alternate config file has been specified
  282.     */
  283.     if ( strstr( lpCmdLine, "-config" ) )
  284.     {
  285.         FILE       *fp;
  286.         const char *name;
  287.         
  288.         name = strstr( lpCmdLine, "-config" ) + strlen( "-config" );
  289.         
  290.         while ( *name && *name == ' ' )
  291.             name++;
  292.         
  293.         if ( ( fp = fopen( name, "rb" ) ) != 0 )
  294.         {
  295.             fread( &cfg, sizeof( cfg ), 1, fp );
  296.             fclose( fp );
  297.             if ( cfg.size == sizeof( cfg ) )
  298.             {
  299.                 s_config = cfg;
  300.                 s_config_specified_on_cmdline = TRUE;
  301.             }
  302.         }
  303.     }
  304.     /*
  305.     ** or try and load the old one
  306.     */
  307.     else
  308.     {
  309.         FILE *fp;
  310.         
  311.         if ( ( fp = fopen( CFGNAME, "rb" ) ) != 0 )
  312.         {
  313.             fread( &cfg, sizeof( cfg ), 1, fp );
  314.             
  315.             if ( cfg.size == sizeof( cfg ) )
  316.                 s_config = cfg;
  317.             fclose( fp );
  318.         }
  319.     }
  320.     
  321.     /*
  322.     ** see if a non-default window width and height have been specified
  323.     */
  324.     {
  325.         const char *widthstring  = strstr( lpCmdLine, "-width:" );
  326.         const char *heightstring = strstr( lpCmdLine, "-height:" );
  327.         
  328.         if ( widthstring )
  329.         {
  330.             widthstring += strlen( "-width:" );
  331.             s_window_width  = atoi( widthstring );
  332.         }
  333.         if ( heightstring )
  334.         {
  335.             heightstring += strlen( "-height:" );
  336.             s_window_height = atoi( heightstring );
  337.         }
  338.         
  339.         if ( s_window_width < 0 || s_window_height < 0 )
  340.         {
  341.             RbMessage( RB_MSG_ERROR, "Invalid command line window size" );
  342.             return FALSE;
  343.         }
  344.     }
  345.     
  346.     if ( strstr( lpCmdLine, "-checkerboard" ) )
  347.     {
  348.         s_config.random_texture = FALSE;
  349.     }
  350.     
  351.     if ( !s_noprompt )
  352.     {
  353.         int rval;
  354.         
  355.         RBCreateOpenGLWindow( hInstance, nCmdShow );
  356.         if ( !RBCreateContext( s_hwndOpenGL ) )
  357.             return FALSE;
  358.  
  359.         
  360.         rval = DialogBox( hInstance, MAKEINTRESOURCE( IDD_DIALOG1 ), 0, DialogProc );
  361.         
  362.         RBDestroyContext( s_hwndOpenGL );
  363.         
  364.         return rval;
  365.     }
  366.     else
  367.     {
  368.         return TRUE;
  369.     }
  370. }
  371.  
  372. /*
  373. ** DialogProc
  374. */
  375. BOOL CALLBACK DialogProc( HWND hWnd, 
  376.                          UINT uMsg,
  377.                          WPARAM wParam,
  378.                          LPARAM lParam )
  379. {
  380.     WORD    wNotifyCode = HIWORD( wParam );
  381.     HMENU   hMenu       = GetMenu( hWnd );
  382.     
  383.     switch( uMsg )
  384.     {
  385.     case WM_INITDIALOG:
  386.         RBInitDialog( hWnd );
  387.         return TRUE;
  388.     case WM_COMMAND:
  389.         switch ( HIWORD( wParam ) )
  390.         {
  391.         case BN_CLICKED:
  392.             {
  393.                 switch( wParam )
  394.                 {
  395.                 case IDOK:
  396.                     RBReadConfigFromDialog( hWnd );
  397.                     RBStoreConfigToDisk();
  398.                     EndDialog( hWnd, RB_OK );
  399.                     return TRUE;
  400.                 case IDCANCEL:
  401.                     EndDialog( hWnd, RB_CANCEL );
  402.                     s_done = TRUE;
  403.                     return TRUE;
  404.                     
  405.                 case IDM_COLORMODE_RGB:
  406.                 case IDM_COLORMODE_INDEX:
  407.                     RBSelectColorMode( hMenu, wParam, hWnd );
  408.                     return TRUE;
  409.                     
  410.                 case IDM_TRIANGLES:
  411.                 case IDM_TRIANGLE_STRIP:
  412.                 case IDM_DRAW_ELEMENTS:
  413.                 case IDM_CLEAR:
  414.                     CheckMenuItem( hMenu, IDM_TRIANGLES, MF_BYCOMMAND | MF_UNCHECKED );
  415.                     CheckMenuItem( hMenu, IDM_TRIANGLE_STRIP, MF_BYCOMMAND | MF_UNCHECKED );
  416.                     CheckMenuItem( hMenu, IDM_DRAW_ELEMENTS, MF_BYCOMMAND | MF_UNCHECKED );
  417.                     CheckMenuItem( hMenu, IDM_CLEAR, MF_BYCOMMAND | MF_UNCHECKED );
  418.  
  419.                     CheckMenuItem( hMenu, wParam, MF_BYCOMMAND | MF_CHECKED );
  420.                     break;
  421.                     
  422.                 case IDM_DRAW_FRONT:
  423.                     CheckMenuItem( hMenu, IDM_DRAW_FRONT, MF_BYCOMMAND | MF_CHECKED );
  424.                     CheckMenuItem( hMenu, IDM_DRAW_BACK, MF_BYCOMMAND | MF_UNCHECKED );
  425.                     return TRUE;
  426.                 case IDM_DRAW_BACK:
  427.                     CheckMenuItem( hMenu, IDM_DRAW_FRONT, MF_BYCOMMAND | MF_UNCHECKED );
  428.                     CheckMenuItem( hMenu, IDM_DRAW_BACK, MF_BYCOMMAND | MF_CHECKED );
  429.                     return TRUE;
  430.                     
  431.                 case IDM_GL_FLAT:
  432.                     CheckMenuItem( hMenu, IDM_GL_FLAT,   MF_BYCOMMAND | MF_CHECKED );
  433.                     CheckMenuItem( hMenu, IDM_GL_SMOOTH, MF_BYCOMMAND | MF_UNCHECKED );
  434.                     return TRUE;
  435.                 case IDM_GL_SMOOTH:
  436.                     CheckMenuItem( hMenu, IDM_GL_SMOOTH, MF_BYCOMMAND | MF_CHECKED );
  437.                     CheckMenuItem( hMenu, IDM_GL_FLAT, MF_BYCOMMAND | MF_UNCHECKED );
  438.                     return TRUE;
  439.                     
  440.                 case IDM_DEPTHSIZE_16:
  441.                     CheckMenuItem( hMenu, IDM_DEPTHSIZE_16, MF_BYCOMMAND | MF_CHECKED );
  442.                     CheckMenuItem( hMenu, IDM_DEPTHSIZE_32, MF_BYCOMMAND | MF_UNCHECKED );
  443.                     return TRUE;
  444.                 case IDM_DEPTHSIZE_32:
  445.                     CheckMenuItem( hMenu, IDM_DEPTHSIZE_32, MF_BYCOMMAND | MF_CHECKED );
  446.                     CheckMenuItem( hMenu, IDM_DEPTHSIZE_16, MF_BYCOMMAND | MF_UNCHECKED );
  447.                     return TRUE;
  448.                     
  449.                 case IDM_DEPTHBUFFER_ENABLE:
  450.                 case IDM_TEXTURE_ENABLE:
  451.                 case IDM_TEXTURE_PERSPECTIVE_CORRECT:
  452.                 case IDM_DITHER:
  453.                 case IDM_FOG_ENABLE:
  454.                 case IDM_FOG_CHEAP:
  455.                 case IDM_DEPTHMASK:
  456.                 case IDM_CLAMP_S:
  457.                 case IDM_CLAMP_T:
  458.                     RBToggleMenuCheck( hMenu, wParam );
  459.                     return TRUE;
  460.                     
  461.                 case IDM_DEPTHBUFFER_CLEAR0:
  462.                     CheckMenuItem( hMenu, IDM_DEPTHBUFFER_CLEAR1, MF_BYCOMMAND | MF_UNCHECKED );
  463.                     CheckMenuItem( hMenu, IDM_DEPTHBUFFER_CLEAR0, MF_BYCOMMAND | MF_CHECKED );
  464.                     return TRUE;
  465.                 case IDM_DEPTHBUFFER_CLEAR1:
  466.                     CheckMenuItem( hMenu, IDM_DEPTHBUFFER_CLEAR1, MF_BYCOMMAND | MF_CHECKED );
  467.                     CheckMenuItem( hMenu, IDM_DEPTHBUFFER_CLEAR0, MF_BYCOMMAND | MF_UNCHECKED );
  468.                     return TRUE;
  469.                     
  470.                 case IDM_FOG_LINEAR:
  471.                 case IDM_FOG_EXP:
  472.                 case IDM_FOG_EXP2:
  473.                     RBSelectFogCurve( hMenu, wParam );
  474.                     return TRUE;
  475.                     
  476.                 case IDM_GL_LESS:
  477.                 case IDM_GL_LEQUAL:
  478.                 case IDM_GL_EQUAL:
  479.                 case IDM_GL_GEQUAL:
  480.                 case IDM_GL_GREATER:
  481.                 case IDM_GL_ALWAYS:
  482.                 case IDM_GL_NEVER:
  483.                 case IDM_GL_NOTEQUAL:
  484.                     RBSelectDepthFunc( hMenu, wParam );
  485.                     return TRUE;
  486.                     
  487.                 case IDM_ZOOM_1x1:
  488.                 case IDM_ZOOM_1x2:
  489.                 case IDM_ZOOM_1x4:
  490.                 case IDM_ZOOM_1x8:
  491.                     RBSelectZoom( hMenu, wParam );
  492.                     return TRUE;
  493.  
  494.                 case IDM_SIZE_3:
  495.                 case IDM_SIZE_10:
  496.                 case IDM_SIZE_25:
  497.                 case IDM_SIZE_50:
  498.                 case IDM_SIZE_100:
  499.                 case IDM_SIZE_1000:
  500.                 case IDM_SIZE_10000:
  501.                     RBSelectTriangleSize( hMenu, wParam );
  502.                     return TRUE;
  503.                     
  504.                 case IDM_TEXTURE_REPLACE:
  505.                 case IDM_TEXTURE_ADD:
  506.                 case IDM_TEXTURE_MODULATE:
  507.                 case IDM_TEXTURE_DECAL:
  508.                     RBSelectTextureEnvironment( hMenu, wParam );
  509.                     return TRUE;
  510. #ifdef NOTYET                    
  511.                 case IDM_TEXTURE_CI:
  512.                 case IDM_TEXTURE_RGB:
  513.                     RBSelectTextureFormat( hMenu, wParam );
  514.                     return TRUE;
  515. #endif
  516.                     
  517.                 case IDM_TEXTURE_WIDTH_1:
  518.                 case IDM_TEXTURE_WIDTH_2:
  519.                 case IDM_TEXTURE_WIDTH_4:
  520.                 case IDM_TEXTURE_WIDTH_8:
  521.                 case IDM_TEXTURE_WIDTH_16:
  522.                 case IDM_TEXTURE_WIDTH_32:
  523.                 case IDM_TEXTURE_WIDTH_64:
  524.                 case IDM_TEXTURE_WIDTH_128:
  525.                 case IDM_TEXTURE_WIDTH_256:
  526.                 case IDM_TEXTURE_WIDTH_512:
  527.                     RBSelectTextureWidth( hMenu, wParam );
  528.                     return TRUE;
  529.                     
  530.                 case IDM_TEXTURE_HEIGHT_1:
  531.                 case IDM_TEXTURE_HEIGHT_2:
  532.                 case IDM_TEXTURE_HEIGHT_4:
  533.                 case IDM_TEXTURE_HEIGHT_8:
  534.                 case IDM_TEXTURE_HEIGHT_16:
  535.                 case IDM_TEXTURE_HEIGHT_32:
  536.                 case IDM_TEXTURE_HEIGHT_64:
  537.                 case IDM_TEXTURE_HEIGHT_128:
  538.                 case IDM_TEXTURE_HEIGHT_256:
  539.                 case IDM_TEXTURE_HEIGHT_512:
  540.                     RBSelectTextureHeight( hMenu, wParam );
  541.                     return TRUE;
  542.                     
  543.                 case IDM_TEXTURE_0:
  544.                 case IDM_TEXTURE_90:
  545.                 case IDM_TEXTURE_180:
  546.                 case IDM_TEXTURE_270:
  547.                     RBSelectTextureOrientation( hMenu, wParam );
  548.                     return TRUE;
  549.                     
  550.                 case IDM_TEXTURE_NEAREST:
  551.                 case IDM_TEXTURE_LINEAR:
  552.                     RBSelectTextureFilter( hMenu, wParam );
  553.                     return TRUE;
  554. }
  555. }
  556. return FALSE;
  557. default:
  558.     return FALSE;
  559. }
  560. return FALSE;
  561. }
  562.  
  563. return FALSE;
  564. }
  565.  
  566. LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  567. {
  568.     switch ( uMsg )
  569.     {
  570.     case WM_CHAR:
  571.     if (wParam == VK_ESCAPE) {
  572.         DestroyWindow(hWnd);
  573.         return 0;
  574.     }
  575.     break;
  576.     case WM_DESTROY:
  577.         PostQuitMessage( 0 );
  578.         return 0;
  579.     }
  580.     return DefWindowProc( hWnd, uMsg, wParam, lParam );
  581. }
  582.  
  583. int RBCreateContext( HWND hWnd )
  584. {
  585.     byte pixelType = s_config.rgb_mode ? PFD_TYPE_RGBA : PFD_TYPE_COLORINDEX;
  586.     PIXELFORMATDESCRIPTOR pfd = 
  587.     { 
  588.         sizeof(PIXELFORMATDESCRIPTOR),   // size of this pfd 
  589.             1,                     // version number 
  590.             PFD_DRAW_TO_WINDOW |   // support window 
  591.             PFD_SUPPORT_OPENGL |   // support OpenGL 
  592.             PFD_DOUBLEBUFFER,      // double buffered 
  593.             pixelType,             // RGBA type 
  594.             16,                    // 16-bit color depth 
  595.             0, 0, 0, 0, 0, 0,      // color bits ignored 
  596.             0,                     // no alpha buffer 
  597.             0,                     // shift bit ignored 
  598.             0,                     // no accumulation buffer 
  599.             0, 0, 0, 0,            // accum bits ignored 
  600.             s_config.depth_size,   // 16-bit z-buffer 
  601.             0,                     // no stencil buffer 
  602.             0,                     // no auxiliary buffer 
  603.             PFD_MAIN_PLANE,        // main layer 
  604.             0,                     // reserved 
  605.             0, 0, 0                // layer masks ignored 
  606.     };
  607.     
  608.     int pf;
  609.     
  610.     s_hGLDC = GetDC( hWnd );
  611.  
  612.     /*
  613.     ** force into RGBA mode if color index in > 8bpp mode
  614.     */
  615.     pfd.cColorBits = GetDeviceCaps( s_hGLDC, BITSPIXEL );
  616.     if ( !s_config.rgb_mode && pfd.cColorBits > 8 )
  617.     {
  618.        pfd.iPixelType = PFD_TYPE_RGBA;
  619.        s_config.rgb_mode = 1;
  620.     }
  621.     
  622.     if ( ( pf = ChoosePixelFormat( s_hGLDC, &pfd ) ) != 0 )
  623.     {
  624.         DescribePixelFormat( s_hGLDC, pf, sizeof( pfd ), &pfd );
  625.         SetPixelFormat( s_hGLDC, pf, &pfd );
  626.         
  627.         s_hglrc = wglCreateContext( s_hGLDC );
  628.         wglMakeCurrent( s_hGLDC, s_hglrc );
  629.         RBSetupPalette( s_hGLDC );
  630.         return 1;
  631.     }
  632.     else
  633.     {
  634.         PVOID lpMsgBuf;
  635.         
  636.         FormatMessage( 
  637.             FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  638.             NULL,
  639.             GetLastError(),
  640.             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  641.             (LPTSTR) &lpMsgBuf,
  642.             0,
  643.             NULL 
  644.             );
  645.         
  646.         // Display the string.
  647.         MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
  648.         
  649.         // Free the buffer.
  650.         LocalFree( lpMsgBuf );
  651.         ReleaseDC( hWnd, s_hGLDC );
  652.         return 0;
  653.     }
  654. }
  655.  
  656. void RBSetupPalette( HDC hDC )
  657. {
  658.     PIXELFORMATDESCRIPTOR pfd;
  659.     LOGPALETTE* pPal;
  660.     int pixelFormat = GetPixelFormat(hDC);
  661.     int paletteSize, status;
  662.     
  663.     status = DescribePixelFormat(hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
  664.     if (!(pfd.dwFlags & PFD_NEED_PALETTE || pfd.iPixelType == PFD_TYPE_COLORINDEX)) {
  665.         return;
  666.     }
  667.     
  668.     paletteSize = 1 << pfd.cColorBits;
  669.     pPal = (LOGPALETTE*)
  670.         malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
  671.     pPal->palVersion = 0x300;
  672.     pPal->palNumEntries = paletteSize;
  673.     
  674.     /* start with a copy of the current system palette */
  675.     (void) GetSystemPaletteEntries(hDC, 0, paletteSize, &pPal->palPalEntry[0]);
  676.     
  677.     if (pfd.iPixelType == PFD_TYPE_RGBA) {
  678.         /* fill in an RGBA color palette */
  679.         int redMask = (1 << pfd.cRedBits) - 1;
  680.         int greenMask = (1 << pfd.cGreenBits) - 1;
  681.         int blueMask = (1 << pfd.cBlueBits) - 1;
  682.         int i;
  683.         
  684.         for (i=0; i<paletteSize; ++i) {
  685.             pPal->palPalEntry[i].peRed =
  686.                 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
  687.             pPal->palPalEntry[i].peGreen =
  688.                 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
  689.             pPal->palPalEntry[i].peBlue =
  690.                 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
  691.             pPal->palPalEntry[i].peFlags = 0;
  692.         }
  693.     } else {
  694.         /* fill in a Color Index ramp color palette */
  695.         int ii;
  696.         int nColors = paletteSize - 20;
  697.         float hStep = (360.0f / (float)nColors);
  698.         PALETTEENTRY *pe = &pPal->palPalEntry[0];
  699.         
  700.         for (ii = 10; ii < paletteSize-10; ii++) {
  701.             /* HSV_to_RGB lifted from Foley, et. al. */
  702.             
  703.             float h = ii * hStep, s = 1.0f, v = 1.0f;
  704.             float r, g, b;
  705.             float ih, fh, p, q, t;
  706.             
  707.             h = h / 60.0f;
  708.             ih = (float) floor(h);
  709.             fh = h - ih;
  710.             
  711.             p = v * (1.0f - s);
  712.             q = v * (1.0f - (s * fh));
  713.             t = v * (1.0f - (s * (1.0f - fh)));
  714.             
  715.             switch ((int) ih) {
  716.             case 0:
  717.                 r = v; g = t; b = p;
  718.                 break;
  719.             case 1:
  720.                 r = q; g = v; b = p;
  721.                 break;
  722.             case 2:
  723.                 r = p; g = v; b = t;
  724.                 break;
  725.             case 3:
  726.                 r = p; g = q; b = v;
  727.                 break;
  728.             case 4:
  729.                 r = t; g = p; b = v;
  730.                 break;
  731.             case 5:
  732.                 r = v; g = p; b = q;
  733.                 break;
  734.             }
  735.             
  736.             pe[ii].peRed   = (BYTE) (r * 255);
  737.             pe[ii].peGreen = (BYTE) (g * 255);
  738.             pe[ii].peBlue  = (BYTE) (b * 255);
  739.             pe[ii].peFlags = PC_NOCOLLAPSE;
  740.         }
  741.         
  742.         s_redIndex   = 10 + 0;
  743.         s_greenIndex = 10 + (nColors >> 1);
  744.         s_blueIndex  = 10 + nColors - 1;
  745.         s_clearIndex = 0;
  746.     }
  747.     
  748.     s_hPalette = CreatePalette(pPal);
  749.     free(pPal);
  750.     
  751.     if ( s_hPalette ) {
  752.         SelectPalette(hDC, s_hPalette, FALSE);
  753.         RealizePalette(hDC);
  754.     }
  755. }
  756.  
  757. void RBShutdown( void )
  758. {
  759. }
  760.  
  761. void RBDestroyContext( HWND hWnd )
  762. {
  763.     wglMakeCurrent( NULL, NULL );
  764.     if ( s_hGLDC )
  765.         ReleaseDC( hWnd, s_hGLDC );
  766.     if ( s_hglrc )
  767.         wglDeleteContext( s_hglrc );
  768.     
  769.     s_hGLDC = 0;
  770.     s_hglrc = 0;
  771. }
  772.  
  773. void RBGo( HINSTANCE hInstance, int nCmdShow )
  774. {
  775.     MSG msg;
  776.     
  777.     memset( &s_stats, 0, sizeof( s_stats ) );
  778.     
  779.     RBCreateOpenGLWindow( hInstance, nCmdShow );
  780.     
  781.     /*
  782.     ** show and update window
  783.     */
  784.     ShowWindow( s_hwndOpenGL, nCmdShow );
  785.     UpdateWindow( s_hwndOpenGL );
  786.  
  787.     /*
  788.     ** create data
  789.     */
  790.     if ( s_elements_data.interleaved_array )
  791.     {
  792.         free( s_elements_data.interleaved_array );
  793.         s_elements_data.interleaved_array = 0;
  794.     }
  795.     if ( s_elements_data.elements_array )
  796.     {
  797.         int i;
  798.  
  799.         for ( i = 0; i < s_elements_data.num_element_rows; i++ )
  800.         {
  801.             free( s_elements_data.elements_array[i] );
  802.         }
  803.  
  804.         free( s_elements_data.elements_array );
  805.         s_elements_data.elements_array = 0;
  806.     }
  807.  
  808.     RBBuildData( s_hwndOpenGL );
  809.     
  810.     if ( s_everything ) 
  811.     {
  812.         FILE* every;
  813.         int zi, si, qi;
  814.         
  815.         every = fopen("every.log", "wt");
  816.         
  817.         RBCreateContext( s_hwndOpenGL );
  818.         s_config.iterations = 200;
  819.         for (zi = 0; zi < 4; zi++) {
  820.             switch (zi) {
  821.             case 0:
  822.                 s_config.do_depth_test = 0;
  823.                 s_config.do_depth_writes = 0;
  824.                 break;
  825.             case 1:
  826.                 s_config.do_depth_test = 1;
  827.                 s_config.depth_func = GL_ALWAYS;
  828.                 s_config.do_depth_writes = 1;
  829.                 break;
  830.             case 2:
  831.                 s_config.do_depth_test = 1;
  832.                 s_config.do_depth_writes = 1;
  833.                 s_config.depth_func = GL_LEQUAL;
  834.                 break;
  835.             case 3:
  836.                 s_config.do_depth_test = 1;
  837.                 s_config.do_depth_writes = 0;
  838.                 s_config.depth_func = GL_EQUAL;
  839.                 break;
  840.             }
  841.             
  842.             for (s_config.do_dither = 0; s_config.do_dither <= 1; s_config.do_dither++) {
  843.                 for (si = 0; si < 2; si++) {
  844.                     switch (si) {
  845.                     case 0:
  846.                         s_config.shade_model = GL_FLAT;
  847.                         break;
  848.                     case 1:
  849.                         s_config.shade_model = GL_SMOOTH;
  850.                         break;
  851.                     }
  852.                     
  853.                     for (qi = 0; qi < 5; qi++) {
  854.                         switch (qi) {
  855.                         case 0:
  856.                             s_config.do_texture = 0;
  857.                             s_config.perspective_correction = GL_FASTEST;
  858.                             s_config.texture_environment = GL_REPLACE;
  859.                             break;
  860.                         case 1:
  861.                             s_config.do_texture = 1;
  862.                             s_config.perspective_correction = GL_FASTEST;
  863.                             s_config.texture_environment = GL_REPLACE;
  864.                             break;
  865.                         case 2:
  866.                             s_config.do_texture = 1;
  867.                             s_config.perspective_correction = GL_FASTEST;
  868.                             s_config.texture_environment = s_config.rgb_mode ? GL_MODULATE : GL_ADD;
  869.                             break;
  870.                         case 3:
  871.                             s_config.do_texture = 1;
  872.                             s_config.perspective_correction = GL_NICEST;
  873.                             s_config.texture_environment = GL_REPLACE;
  874.                             break;
  875.                         case 4:
  876.                             s_config.do_texture = 1;
  877.                             s_config.perspective_correction = GL_NICEST;
  878.                             s_config.texture_environment = s_config.rgb_mode ? GL_MODULATE : GL_ADD;
  879.                             break;
  880.                         }
  881.                         
  882.                         RBConfigOpenGL();
  883.                         s_stats.triangles_rendered = 0;
  884.                         s_stats.area_filled = 0.0F;
  885.                         RBDoTest( s_hwndOpenGL );
  886.                         
  887.                         {
  888.                             char msg[80];
  889.                             
  890.                             sprintf(msg,
  891.                                 "zi=%d, d=%d, si=%d, qi=%d % 7.3f MPixel/s",
  892.                                 zi,
  893.                                 s_config.do_dither,
  894.                                 si,
  895.                                 qi,
  896.                                 s_stats.mpixels_second);
  897.                             SetWindowText( s_hwndOpenGL, msg );
  898.                         }
  899.                         if ( s_config.draw_buffer == GL_BACK )
  900.                             SwapBuffers( s_hGLDC );
  901.                         
  902.                         fprintf(every, "% 7.3f", s_stats.mpixels_second);
  903.                     }
  904.                 }
  905.                 fprintf(every, "\n");
  906.             }
  907.         }
  908.         
  909.         fclose(every);
  910.         RBDestroyContext( s_hwndOpenGL );
  911.         
  912.     } else {
  913.         RBCreateContext( s_hwndOpenGL );
  914.         RBConfigOpenGL();
  915.         
  916.         RBDoTest( s_hwndOpenGL );
  917.         
  918.         if ( s_config.draw_buffer == GL_BACK )
  919.             SwapBuffers( s_hGLDC );
  920.     }
  921.     
  922.     if ( s_noprompt )
  923.         PostMessage( s_hwndOpenGL, WM_CLOSE, 0, 0 );
  924.     
  925.     while ( GetMessage( &msg, NULL, 0, 0 ) )
  926.     {
  927.         TranslateMessage( &msg );
  928.         DispatchMessage( &msg );
  929.     }
  930.     
  931.     RBDestroyContext( s_hwndOpenGL );
  932. }
  933.  
  934. HWND RBCreateOpenGLWindow( HINSTANCE hInstance, int nCmdShow )
  935. {
  936.     WNDCLASSEX wc;
  937.     
  938.     /*
  939.     ** register a window class
  940.     */
  941.     memset( &wc, 0, sizeof( wc ) );
  942.     
  943.     wc.cbSize            = sizeof( wc );
  944.     wc.style             = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
  945.     wc.lpfnWndProc       = WndProc;
  946.     wc.cbClsExtra        = 0;
  947.     wc.cbWndExtra        = 0;
  948.     wc.hInstance         = hInstance;
  949.     wc.hIcon             = LoadIcon( NULL, IDI_APPLICATION );
  950.     wc.hCursor           = LoadCursor( NULL, IDC_ARROW );
  951.     wc.hbrBackground     = (HBRUSH) GetStockObject( WHITE_BRUSH );
  952.     wc.lpszMenuName      = NULL;
  953.     wc.lpszClassName     = "RB Canvas";
  954.     wc.hIconSm           = LoadIcon( NULL, IDI_APPLICATION );
  955.     
  956.     RegisterClassEx( &wc );
  957.     
  958.     /*
  959.     ** create a window
  960.     */
  961.     if ( ( s_hwndOpenGL = CreateWindow( "RB Canvas",
  962.         APPNAME,
  963.         WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
  964.         0, 0, s_window_width, s_window_height,
  965.         NULL,
  966.         NULL,
  967.         hInstance,
  968.         NULL ) ) == NULL )
  969.     {
  970.         return NULL;
  971.     }
  972.     
  973.     return s_hwndOpenGL;
  974. }
  975.  
  976. void RBInitDialog( HWND hDlg )
  977. {
  978.     char         buffer[1024];
  979.     HMENU        hMenu;
  980.     char         iterationsbuffer[1024];
  981.     char         vendorbuffer[1024];
  982.     
  983.  
  984.     if ( strstr( glGetString( GL_EXTENSIONS ), "GL_SGI_index_texture " ) )
  985.         s_index_texture_extension = TRUE;
  986.  
  987.     strcpy( vendorbuffer, glGetString( GL_VENDOR ) );
  988.     strupr( vendorbuffer );
  989.     
  990.     sprintf( buffer, "\n  OEM:\t\t%s  \n  Version:\t%s\n  Renderer:\t%s\n", glGetString( GL_VENDOR ), glGetString( GL_VERSION ), glGetString( GL_RENDERER ) );
  991.     SetDlgItemText( hDlg, IDC_OEMINFO, buffer );
  992.     
  993.     hMenu = GetMenu( hDlg );
  994.     
  995.     if ( s_config.do_depth_test )
  996.         CheckMenuItem( hMenu, IDM_DEPTHBUFFER_ENABLE, MF_BYCOMMAND | MF_CHECKED );
  997.     else
  998.         CheckMenuItem( hMenu, IDM_DEPTHBUFFER_ENABLE, MF_BYCOMMAND | MF_UNCHECKED );
  999.     
  1000.     if ( s_config.do_depth_writes )
  1001.         CheckMenuItem( hMenu, IDM_DEPTHMASK, MF_BYCOMMAND | MF_CHECKED );
  1002.     else
  1003.         CheckMenuItem( hMenu, IDM_DEPTHMASK, MF_BYCOMMAND | MF_UNCHECKED );
  1004.     
  1005.     if ( s_config.depth_size == 16 )
  1006.         SendMessage( hDlg, WM_COMMAND, IDM_DEPTHSIZE_16, 0 );
  1007.     else
  1008.         SendMessage( hDlg, WM_COMMAND, IDM_DEPTHSIZE_32, 0 );
  1009.     
  1010.     if ( s_config.depth_clear == 0.0F )
  1011.         SendMessage( hDlg, WM_COMMAND, IDM_DEPTHBUFFER_CLEAR0, 0 );
  1012.     else
  1013.         SendMessage( hDlg, WM_COMMAND, IDM_DEPTHBUFFER_CLEAR1, 0 );
  1014.     
  1015.     if ( s_config.primitive == IDM_TRIANGLES )
  1016.         SendMessage( hDlg, WM_COMMAND, IDM_TRIANGLES, 0 );
  1017.     else if ( s_config.primitive == IDM_TRIANGLE_STRIP )
  1018.         SendMessage( hDlg, WM_COMMAND, IDM_TRIANGLE_STRIP, 0 );
  1019.     else if ( s_config.primitive == IDM_DRAW_ELEMENTS )
  1020.         SendMessage( hDlg, WM_COMMAND, IDM_DRAW_ELEMENTS, 0 );
  1021.     else if ( s_config.primitive == IDM_CLEAR )
  1022.         SendMessage( hDlg, WM_COMMAND, IDM_CLEAR, 0 );
  1023.     
  1024.     switch ( s_config.depth_func )
  1025.     {
  1026.     case GL_LESS:
  1027.         SendMessage( hDlg, WM_COMMAND, IDM_GL_LESS, 0 );
  1028.         break;
  1029.     case GL_LEQUAL:
  1030.         SendMessage( hDlg, WM_COMMAND, IDM_GL_LEQUAL, 0 );
  1031.         break;
  1032.     case GL_EQUAL:
  1033.         SendMessage( hDlg, WM_COMMAND, IDM_GL_EQUAL, 0 );
  1034.         break;
  1035.     case GL_GEQUAL:
  1036.         SendMessage( hDlg, WM_COMMAND, IDM_GL_GEQUAL, 0 );
  1037.         break;
  1038.     case GL_GREATER:
  1039.         SendMessage( hDlg, WM_COMMAND, IDM_GL_GREATER, 0 );
  1040.         break;
  1041.     case GL_ALWAYS:
  1042.         SendMessage( hDlg, WM_COMMAND, IDM_GL_ALWAYS, 0 );
  1043.         break;
  1044.     case GL_NEVER:
  1045.         SendMessage( hDlg, WM_COMMAND, IDM_GL_NEVER, 0 );
  1046.         break;
  1047.     case GL_NOTEQUAL:
  1048.         SendMessage( hDlg, WM_COMMAND, IDM_GL_NOTEQUAL, 0 );
  1049.         break;
  1050.     }
  1051.     
  1052.     if ( s_config.do_fog )
  1053.         CheckMenuItem( hMenu, IDM_FOG_ENABLE, MF_BYCOMMAND | MF_CHECKED );
  1054.     else
  1055.         CheckMenuItem( hMenu, IDM_FOG_ENABLE, MF_BYCOMMAND | MF_UNCHECKED );
  1056.     
  1057.     if ( s_config.do_cheap_fog )
  1058.         CheckMenuItem( hMenu, IDM_FOG_CHEAP, MF_BYCOMMAND | MF_CHECKED );
  1059.     else
  1060.         CheckMenuItem( hMenu, IDM_FOG_CHEAP, MF_BYCOMMAND | MF_UNCHECKED );
  1061.     
  1062.     switch ( s_config.fog_curve )
  1063.     {
  1064.     case GL_LINEAR:
  1065.         SendMessage( hDlg, WM_COMMAND, IDM_FOG_LINEAR, 0 );
  1066.         break;
  1067.     case GL_EXP:
  1068.         SendMessage( hDlg, WM_COMMAND, IDM_FOG_EXP, 0 );
  1069.         break;
  1070.     case GL_EXP2:
  1071.         SendMessage( hDlg, WM_COMMAND, IDM_FOG_EXP2, 0 );
  1072.         break;
  1073.     }
  1074.     
  1075.     if ( s_config.rgb_mode )
  1076.         SendMessage( hDlg, WM_COMMAND, IDM_COLORMODE_RGB, 0 );
  1077.     else
  1078.         SendMessage( hDlg, WM_COMMAND, IDM_COLORMODE_INDEX, 0 );
  1079.     
  1080.     if ( s_config.do_dither )
  1081.         CheckMenuItem( hMenu, IDM_DITHER, MF_BYCOMMAND | MF_CHECKED );
  1082.     else
  1083.         CheckMenuItem( hMenu, IDM_DITHER, MF_BYCOMMAND | MF_UNCHECKED );
  1084.     
  1085.     if ( s_config.draw_buffer == GL_FRONT )
  1086.         SendMessage( hDlg, WM_COMMAND, IDM_DRAW_FRONT, 0 );
  1087.     else
  1088.         SendMessage( hDlg, WM_COMMAND, IDM_DRAW_BACK, 0 );
  1089.     
  1090.     if ( s_config.shade_model == GL_FLAT )
  1091.         SendMessage( hDlg, WM_COMMAND, IDM_GL_FLAT, 0 );
  1092.     else
  1093.         SendMessage( hDlg, WM_COMMAND, IDM_GL_SMOOTH, 0 );
  1094.     
  1095.     sprintf( iterationsbuffer, "%d", s_config.iterations );
  1096.     SetDlgItemText( hDlg, IDC_ITERATIONS, iterationsbuffer );
  1097.     
  1098.     switch ( s_config.triangle_size )
  1099.     {
  1100.     case 3:
  1101.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_3, 0 );
  1102.         break;
  1103.     case 10:
  1104.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_10, 0 );
  1105.         break;
  1106.     case 25:
  1107.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_25, 0 );
  1108.         break;
  1109.     case 50:
  1110.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_50, 0 );
  1111.         break;
  1112.     case 100:
  1113.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_100, 0 );
  1114.         break;
  1115.     case 1000:
  1116.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_1000, 0 );
  1117.         break;
  1118.     case 10000:
  1119.         SendMessage( hDlg, WM_COMMAND, IDM_SIZE_10000, 0 );
  1120.         break;
  1121.     }
  1122.     
  1123.     /*
  1124.     ** configure texture mapping
  1125.     */
  1126.     if ( s_config.texture_zoom == 1.0F )
  1127.         SendMessage( hDlg, WM_COMMAND, IDM_ZOOM_1x1, 0 );
  1128.     else if ( s_config.texture_zoom == 2.0F )
  1129.         SendMessage( hDlg, WM_COMMAND, IDM_ZOOM_1x2, 0 );
  1130.     else if ( s_config.texture_zoom == 4.0F )
  1131.         SendMessage( hDlg, WM_COMMAND, IDM_ZOOM_1x4, 0 );
  1132.     else
  1133.         SendMessage( hDlg, WM_COMMAND, IDM_ZOOM_1x8, 0 );
  1134.     
  1135.     if ( s_config.do_texture )
  1136.         CheckMenuItem( hMenu, IDM_TEXTURE_ENABLE, MF_BYCOMMAND | MF_CHECKED );
  1137.     else
  1138.         CheckMenuItem( hMenu, IDM_TEXTURE_ENABLE, MF_BYCOMMAND | MF_UNCHECKED );
  1139.     
  1140.     if ( s_config.perspective_correction == GL_NICEST )
  1141.         CheckMenuItem( hMenu, IDM_TEXTURE_PERSPECTIVE_CORRECT, MF_BYCOMMAND | MF_CHECKED );
  1142.     else
  1143.         CheckMenuItem( hMenu, IDM_TEXTURE_PERSPECTIVE_CORRECT, MF_BYCOMMAND | MF_UNCHECKED );
  1144.     
  1145.     if ( s_config.texture_clamp_s )
  1146.         CheckMenuItem( hMenu, IDM_CLAMP_S, MF_BYCOMMAND | MF_CHECKED );
  1147.     else
  1148.         CheckMenuItem( hMenu, IDM_CLAMP_S, MF_BYCOMMAND | MF_UNCHECKED );
  1149.     
  1150.     if ( s_config.texture_clamp_t )
  1151.         CheckMenuItem( hMenu, IDM_CLAMP_T, MF_BYCOMMAND | MF_CHECKED );
  1152.     else
  1153.         CheckMenuItem( hMenu, IDM_CLAMP_T, MF_BYCOMMAND | MF_UNCHECKED );
  1154.     
  1155.     
  1156.     if ( !s_index_texture_extension )
  1157.     {
  1158.         if ( s_config.texture_environment == GL_ADD )
  1159.             s_config.texture_environment = GL_DECAL;
  1160.         EnableMenuItem( hMenu, IDM_TEXTURE_ADD, MF_BYCOMMAND | MF_GRAYED );
  1161.     }
  1162.     
  1163.     switch ( s_config.texture_environment )
  1164.     {
  1165.     case GL_ADD:
  1166.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_ADD, 0 );
  1167.         break;
  1168.     case GL_DECAL:
  1169.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_DECAL, 0 );
  1170.         break;
  1171.     case GL_REPLACE:
  1172.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_REPLACE, 0 );
  1173.         break;
  1174.     case GL_MODULATE:
  1175.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_MODULATE, 0 );
  1176.         break;
  1177.     }
  1178.     
  1179.     switch ( s_config.texture_width )
  1180.     {
  1181.     case 1:
  1182.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_1, 0 );
  1183.         break;
  1184.     case 2:
  1185.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_2, 0 );
  1186.         break;
  1187.     case 4:
  1188.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_4, 0 );
  1189.         break;
  1190.     case 8:
  1191.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_8, 0 );
  1192.         break;
  1193.     case 16:
  1194.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_16, 0 );
  1195.         break;
  1196.     case 32:
  1197.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_32, 0 );
  1198.         break;
  1199.     case 64:
  1200.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_64, 0 );
  1201.         break;
  1202.     case 128:
  1203.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_128, 0 );
  1204.         break;
  1205.     case 256:
  1206.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_256, 0 );
  1207.         break;
  1208.     case 512:
  1209.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_WIDTH_512, 0 );
  1210.         break;
  1211.     }
  1212.     
  1213.     switch ( s_config.texture_height )
  1214.     {
  1215.     case 1:
  1216.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_1, 0 );
  1217.         break;
  1218.     case 2:
  1219.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_2, 0 );
  1220.         break;
  1221.     case 4:
  1222.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_4, 0 );
  1223.         break;
  1224.     case 8:
  1225.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_8, 0 );
  1226.         break;
  1227.     case 16:
  1228.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_16, 0 );
  1229.         break;
  1230.     case 32:
  1231.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_32, 0 );
  1232.         break;
  1233.     case 64:
  1234.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_64, 0 );
  1235.         break;
  1236.     case 128:
  1237.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_128, 0 );
  1238.         break;
  1239.     case 256:
  1240.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_256, 0 );
  1241.         break;
  1242.     case 512:
  1243.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_HEIGHT_512, 0 );
  1244.         break;
  1245.     }
  1246.     
  1247.     switch ( s_config.texture_orientation )
  1248.     {
  1249.     case 0:
  1250.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_0, 0 );
  1251.         break;
  1252.     case 90:
  1253.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_90, 0 );
  1254.         break;
  1255.     case 180:
  1256.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_180, 0 );
  1257.         break;
  1258.     case 270:
  1259.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_270, 0 );
  1260.         break;
  1261.     }
  1262.     
  1263.     switch ( s_config.texture_filter )
  1264.     {
  1265.     case GL_NEAREST:
  1266.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_NEAREST, 0 );
  1267.         break;
  1268.     case GL_LINEAR:
  1269.         SendMessage( hDlg, WM_COMMAND, IDM_TEXTURE_LINEAR, 0 );
  1270.         break;
  1271.     }
  1272.  
  1273. #ifdef NOTYET
  1274.     if ( !s_index_texture_extension )
  1275.     {
  1276.         EnableMenuItem( hMenu, IDM_TEXTURE_CI, MF_BYCOMMAND | MF_GRAYED );
  1277.         if ( s_config.texture_format == IDM_TEXTURE_CI )
  1278.             s_config.texture_format = IDM_TEXTURE_RGB;
  1279.     }
  1280.     SendMessage( hDlg, WM_COMMAND, s_config.texture_format, 0 );
  1281. #endif
  1282.     
  1283. }
  1284.  
  1285. void RBReadConfigFromDialog( HWND hDlg )
  1286. {
  1287.     char  buffer[1024];
  1288.     char *endptr;
  1289.     HMENU hMenu = GetMenu( hDlg );
  1290.     
  1291.     /*
  1292.     ** configure test parameters
  1293.     */
  1294.     GetWindowText( GetDlgItem( hDlg, IDC_ITERATIONS ), buffer, 1023 );
  1295.     s_config.iterations = strtol( buffer, &endptr, 10 );
  1296.     
  1297.     if ( RBMenuItemIsChecked( hMenu, IDM_DRAW_FRONT ) )
  1298.         s_config.draw_buffer = GL_FRONT;
  1299.     else
  1300.         s_config.draw_buffer = GL_BACK;
  1301.     
  1302.         /*
  1303.         ** configure attributes
  1304.     */
  1305.     s_config.rgb_mode = RBMenuItemIsChecked( hMenu, IDM_COLORMODE_RGB );
  1306.     
  1307.     s_config.do_dither = RBMenuItemIsChecked( hMenu, IDM_DITHER );
  1308.    
  1309.     if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_3 ) )
  1310.         s_config.triangle_size = 3;
  1311.     else if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_10 ) )
  1312.         s_config.triangle_size = 10;
  1313.     else if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_25 ) )
  1314.         s_config.triangle_size = 25;
  1315.     else if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_50 ) )
  1316.         s_config.triangle_size = 50;
  1317.     else if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_100 ) )
  1318.         s_config.triangle_size = 100;
  1319.     else if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_1000 ) )
  1320.         s_config.triangle_size = 1000;
  1321.     else if ( RBMenuItemIsChecked( hMenu, IDM_SIZE_10000 ) )
  1322.         s_config.triangle_size = 10000;
  1323.     
  1324.     if ( RBMenuItemIsChecked( hMenu, IDM_GL_SMOOTH ) )
  1325.         s_config.shade_model = GL_SMOOTH;
  1326.     else 
  1327.         s_config.shade_model = GL_FLAT;
  1328.     
  1329.     if ( RBMenuItemIsChecked( hMenu, IDM_TRIANGLES ) )
  1330.         s_config.primitive = IDM_TRIANGLES;
  1331.     else if ( RBMenuItemIsChecked( hMenu, IDM_TRIANGLE_STRIP ) )
  1332.         s_config.primitive = IDM_TRIANGLE_STRIP;
  1333.     else if ( RBMenuItemIsChecked( hMenu, IDM_DRAW_ELEMENTS ) )
  1334.         s_config.primitive = IDM_DRAW_ELEMENTS;
  1335.     else if ( RBMenuItemIsChecked( hMenu, IDM_CLEAR ) )
  1336.         s_config.primitive = IDM_CLEAR;
  1337.     
  1338.         /*
  1339.         ** configure depth buffer variables
  1340.     */
  1341.     s_config.do_depth_test   = RBMenuItemIsChecked( hMenu, IDM_DEPTHBUFFER_ENABLE );
  1342.     s_config.do_depth_writes = RBMenuItemIsChecked( hMenu, IDM_DEPTHMASK );
  1343.     if ( RBMenuItemIsChecked( hMenu, IDM_DEPTHSIZE_16 ) )
  1344.         s_config.depth_size = 16;
  1345.     else
  1346.         s_config.depth_size = 32;
  1347.     
  1348.     if ( RBMenuItemIsChecked( hMenu, IDM_DEPTHBUFFER_CLEAR0 ) )
  1349.         s_config.depth_clear = 0.0F;
  1350.     else
  1351.         s_config.depth_clear = 1.0F;
  1352.     
  1353.     if ( RBMenuItemIsChecked( hMenu, IDM_GL_LESS ) )
  1354.         s_config.depth_func = GL_LESS;
  1355.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_LEQUAL ) )
  1356.         s_config.depth_func = GL_LEQUAL;
  1357.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_EQUAL ) )
  1358.         s_config.depth_func = GL_EQUAL;
  1359.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_GREATER ) )
  1360.         s_config.depth_func = GL_GREATER;
  1361.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_GEQUAL ) )
  1362.         s_config.depth_func = GL_GEQUAL;
  1363.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_ALWAYS ) )
  1364.         s_config.depth_func = GL_ALWAYS;
  1365.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_NEVER ) )
  1366.         s_config.depth_func = GL_NEVER;
  1367.     else if ( RBMenuItemIsChecked( hMenu, IDM_GL_NOTEQUAL ) )
  1368.         s_config.depth_func = GL_NOTEQUAL;
  1369.     
  1370.         /*
  1371.         ** configure texture map variables
  1372.     */
  1373.     s_config.do_texture = RBMenuItemIsChecked( hMenu, IDM_TEXTURE_ENABLE );
  1374.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_PERSPECTIVE_CORRECT ) )
  1375.         s_config.perspective_correction = GL_NICEST;
  1376.     else
  1377.         s_config.perspective_correction = GL_FASTEST;
  1378.     
  1379.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_0 ) )
  1380.         s_config.texture_orientation = 0;
  1381.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_90 ) )
  1382.         s_config.texture_orientation = 90;
  1383.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_180 ) )
  1384.         s_config.texture_orientation = 180;
  1385.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_270 ) )
  1386.         s_config.texture_orientation = 270;
  1387.     
  1388.     if ( RBMenuItemIsChecked( hMenu, IDM_ZOOM_1x1 ) )
  1389.         s_config.texture_zoom = 1.0F;
  1390.     else if ( RBMenuItemIsChecked( hMenu, IDM_ZOOM_1x2 ) )
  1391.         s_config.texture_zoom = 2.0F;
  1392.     else if ( RBMenuItemIsChecked( hMenu, IDM_ZOOM_1x4 ) )
  1393.         s_config.texture_zoom = 4.0F;
  1394.     else if ( RBMenuItemIsChecked( hMenu, IDM_ZOOM_1x8 ) )
  1395.         s_config.texture_zoom = 8.0F;
  1396.  
  1397. #ifdef NOTYET    
  1398.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_CI ) )
  1399.         s_config.texture_format = IDM_TEXTURE_CI;
  1400.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_RGB ) )
  1401.         s_config.texture_format = IDM_TEXTURE_RGB;
  1402. #endif
  1403.     
  1404.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_DECAL ) )
  1405.         s_config.texture_environment = GL_DECAL;
  1406.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_REPLACE ) )
  1407.         s_config.texture_environment = GL_REPLACE;
  1408.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_MODULATE ) )
  1409.         s_config.texture_environment = GL_MODULATE;
  1410.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_ADD ) )
  1411.         s_config.texture_environment = GL_ADD;
  1412.     
  1413.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_1 ) )
  1414.         s_config.texture_width = 1;
  1415.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_2 ) )
  1416.         s_config.texture_width = 2;
  1417.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_4 ) )
  1418.         s_config.texture_width = 4;
  1419.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_8 ) )
  1420.         s_config.texture_width = 8;
  1421.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_16 ) )
  1422.         s_config.texture_width = 16;
  1423.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_32 ) )
  1424.         s_config.texture_width = 32;
  1425.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_64 ) )
  1426.         s_config.texture_width = 64;
  1427.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_128 ) )
  1428.         s_config.texture_width = 128;
  1429.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_256 ) )
  1430.         s_config.texture_width = 256;
  1431.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_WIDTH_512 ) )
  1432.         s_config.texture_width = 512;
  1433.     
  1434.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_1 ) )
  1435.         s_config.texture_height = 1;
  1436.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_2 ) )
  1437.         s_config.texture_height = 2;
  1438.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_4 ) )
  1439.         s_config.texture_height = 4;
  1440.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_8 ) )
  1441.         s_config.texture_height = 8;
  1442.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_16 ) )
  1443.         s_config.texture_height = 16;
  1444.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_32 ) )
  1445.         s_config.texture_height = 32;
  1446.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_64 ) )
  1447.         s_config.texture_height = 64;
  1448.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_128 ) )
  1449.         s_config.texture_height = 128;
  1450.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_256 ) )
  1451.         s_config.texture_height = 256;
  1452.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_HEIGHT_512 ) )
  1453.         s_config.texture_height = 512;
  1454.     
  1455.     if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_NEAREST ) )
  1456.         s_config.texture_filter = GL_NEAREST;
  1457.     else if ( RBMenuItemIsChecked( hMenu, IDM_TEXTURE_LINEAR ) )
  1458.         s_config.texture_filter = GL_LINEAR;
  1459.     
  1460.     s_config.ftexture_width  = ( float ) s_config.texture_width;
  1461.     s_config.ftexture_height = ( float ) s_config.texture_height;
  1462.     
  1463.     
  1464.     s_config.texture_clamp_s = RBMenuItemIsChecked( hMenu, IDM_CLAMP_S );
  1465.     s_config.texture_clamp_s = RBMenuItemIsChecked( hMenu, IDM_CLAMP_T );
  1466.     
  1467.     /*
  1468.     ** configure fog parameters
  1469.     */
  1470.     s_config.do_fog       = RBMenuItemIsChecked( hMenu, IDM_FOG_ENABLE );
  1471.     s_config.do_cheap_fog = RBMenuItemIsChecked( hMenu, IDM_FOG_CHEAP );
  1472.     if ( RBMenuItemIsChecked( hMenu, IDM_FOG_LINEAR ) )
  1473.         s_config.fog_curve = GL_LINEAR;
  1474.     else if ( RBMenuItemIsChecked( hMenu, IDM_FOG_EXP ) )
  1475.         s_config.fog_curve = GL_EXP;
  1476.     else if ( RBMenuItemIsChecked( hMenu, IDM_FOG_EXP2 ) )
  1477.         s_config.fog_curve = GL_EXP2;
  1478.     
  1479. }
  1480.  
  1481. void RBConfigOpenGL( void )
  1482. {
  1483.     glMatrixMode( GL_PROJECTION );
  1484.     glLoadIdentity();
  1485.     glOrtho(0.0, s_window_width, 0.0, s_window_height, 0.0, 1.0);
  1486.     glMatrixMode( GL_MODELVIEW );
  1487.     glLoadIdentity();
  1488.     
  1489.     glDrawBuffer( s_config.draw_buffer );
  1490.     
  1491.     glShadeModel( s_config.shade_model );
  1492.     
  1493.     glDisable( GL_CULL_FACE );
  1494.     
  1495.     if (s_config.rgb_mode)
  1496.         glClearColor( 0.2F, 0.0F, 0.4F, 0.0F );
  1497.     else
  1498.         glClearIndex( (float) s_clearIndex );
  1499.     
  1500.     if ( s_config.do_fog )
  1501.     {
  1502.         float color[4] = { 1.0F, 1.0F, 1.0F, 1.0F };
  1503.         
  1504.         glEnable( GL_FOG );
  1505.         glFogi( GL_FOG_MODE, s_config.fog_curve );
  1506.         glFogfv( GL_FOG_COLOR, color );
  1507.         
  1508.         if ( s_config.do_cheap_fog )
  1509.         {
  1510.             glHint( GL_FOG_HINT, GL_FASTEST );
  1511.         }
  1512.         else
  1513.         {
  1514.             glHint( GL_FOG_HINT, GL_NICEST );
  1515.         }
  1516.     }
  1517.     
  1518.     if ( s_config.do_depth_test )
  1519.         glEnable( GL_DEPTH_TEST );
  1520.     else
  1521.         glDisable( GL_DEPTH_TEST );
  1522.     
  1523.     glDepthMask( ( GLboolean ) s_config.do_depth_writes );
  1524.     glClearDepth( s_config.depth_clear );
  1525.     glDepthFunc( s_config.depth_func );
  1526.     
  1527.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  1528.     
  1529.     if ( s_config.do_dither )
  1530.         glEnable( GL_DITHER );
  1531.     else
  1532.         glDisable( GL_DITHER );
  1533.     
  1534.     if ( s_config.do_texture )
  1535.     {
  1536.         glEnable( GL_TEXTURE_2D );
  1537.         glHint( GL_PERSPECTIVE_CORRECTION_HINT, s_config.perspective_correction );
  1538.         glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, s_config.texture_environment );
  1539.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, s_config.texture_filter );
  1540.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, s_config.texture_filter );
  1541.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, s_config.texture_clamp_s ? GL_CLAMP : GL_REPEAT );
  1542.         glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, s_config.texture_clamp_t ? GL_CLAMP : GL_REPEAT );
  1543.         RBCreateTexture();
  1544.     } else {
  1545.         glDisable( GL_TEXTURE_2D );
  1546.     }
  1547. }
  1548.  
  1549. int RBMenuItemIsChecked( HMENU hMenu, WPARAM wID )
  1550. {
  1551.     MENUITEMINFO mif;
  1552.     
  1553.     mif.cbSize = sizeof( mif );
  1554.     mif.fMask  = MIIM_STATE;
  1555.     
  1556.     GetMenuItemInfo( hMenu, wID, FALSE, &mif );
  1557.     
  1558.     return ( ( mif.fState & MFS_CHECKED ) != 0 );
  1559. }
  1560.  
  1561. void RBToggleMenuCheck( HMENU hMenu, WPARAM wID )
  1562. {
  1563.     if ( RBMenuItemIsChecked( hMenu, wID ) )
  1564.         CheckMenuItem( hMenu, wID, MF_BYCOMMAND | MF_UNCHECKED );
  1565.     else
  1566.         CheckMenuItem( hMenu, wID, MF_BYCOMMAND | MF_CHECKED );
  1567. }
  1568.  
  1569. #define CHECKITEM( A ) CheckMenuItem( hMenu, A, MF_BYCOMMAND | ( ( wID == A ) ? MF_CHECKED : MF_UNCHECKED ) )
  1570.  
  1571. void RBSelectColorMode( HMENU hMenu, WPARAM wID, HWND hDlg )
  1572. {
  1573.     CHECKITEM( IDM_COLORMODE_RGB );
  1574.     CHECKITEM( IDM_COLORMODE_INDEX );
  1575.  
  1576.     if ( wID == IDM_COLORMODE_INDEX && !s_index_texture_extension )
  1577.     {
  1578.         EnableMenuItem( hMenu, 3, MF_BYPOSITION | MF_GRAYED );
  1579.     }
  1580.     else
  1581.     {
  1582.         EnableMenuItem( hMenu, 3, MF_BYPOSITION | MF_ENABLED );
  1583.     }
  1584.     DrawMenuBar( hDlg );
  1585. }
  1586.  
  1587. void RBSelectDepthFunc( HMENU hMenu, WPARAM wID )
  1588. {
  1589.     CHECKITEM( IDM_GL_LESS );
  1590.     CHECKITEM( IDM_GL_LEQUAL );
  1591.     CHECKITEM( IDM_GL_EQUAL );
  1592.     CHECKITEM( IDM_GL_GEQUAL );
  1593.     CHECKITEM( IDM_GL_GREATER );
  1594.     CHECKITEM( IDM_GL_ALWAYS );
  1595.     CHECKITEM( IDM_GL_NEVER );
  1596.     CHECKITEM( IDM_GL_NOTEQUAL );
  1597. }
  1598.  
  1599. void RBSelectTextureEnvironment( HMENU hMenu, WPARAM wID )
  1600. {
  1601.     CHECKITEM( IDM_TEXTURE_ADD );
  1602.     CHECKITEM( IDM_TEXTURE_DECAL );
  1603.     CHECKITEM( IDM_TEXTURE_MODULATE );
  1604.     CHECKITEM( IDM_TEXTURE_REPLACE );
  1605. }
  1606.  
  1607. #ifdef NOTYET
  1608. void RBSelectTextureFormat( HMENU hMenu, WPARAM wID )
  1609. {
  1610.     CHECKITEM( IDM_TEXTURE_CI );
  1611.     CHECKITEM( IDM_TEXTURE_RGB );
  1612. }
  1613. #endif
  1614.  
  1615. void RBSelectTextureHeight( HMENU hMenu, WPARAM wID )
  1616. {
  1617.     CHECKITEM( IDM_TEXTURE_HEIGHT_1 );
  1618.     CHECKITEM( IDM_TEXTURE_HEIGHT_2 );
  1619.     CHECKITEM( IDM_TEXTURE_HEIGHT_4 );
  1620.     CHECKITEM( IDM_TEXTURE_HEIGHT_8 );
  1621.     CHECKITEM( IDM_TEXTURE_HEIGHT_16 );
  1622.     CHECKITEM( IDM_TEXTURE_HEIGHT_32 );
  1623.     CHECKITEM( IDM_TEXTURE_HEIGHT_64 );
  1624.     CHECKITEM( IDM_TEXTURE_HEIGHT_128 );
  1625.     CHECKITEM( IDM_TEXTURE_HEIGHT_256 );
  1626.     CHECKITEM( IDM_TEXTURE_HEIGHT_512 );
  1627. }
  1628.  
  1629. void RBSelectTextureWidth( HMENU hMenu, WPARAM wID )
  1630. {
  1631.     CHECKITEM( IDM_TEXTURE_WIDTH_1 );
  1632.     CHECKITEM( IDM_TEXTURE_WIDTH_2 );
  1633.     CHECKITEM( IDM_TEXTURE_WIDTH_4 );
  1634.     CHECKITEM( IDM_TEXTURE_WIDTH_8 );
  1635.     CHECKITEM( IDM_TEXTURE_WIDTH_16 );
  1636.     CHECKITEM( IDM_TEXTURE_WIDTH_32 );
  1637.     CHECKITEM( IDM_TEXTURE_WIDTH_64 );
  1638.     CHECKITEM( IDM_TEXTURE_WIDTH_128 );
  1639.     CHECKITEM( IDM_TEXTURE_WIDTH_256 );
  1640.     CHECKITEM( IDM_TEXTURE_WIDTH_512 );
  1641. }
  1642.  
  1643. void RBSelectTextureOrientation( HMENU hMenu, WPARAM wID )
  1644. {
  1645.     CHECKITEM( IDM_TEXTURE_0 );
  1646.     CHECKITEM( IDM_TEXTURE_90 );
  1647.     CHECKITEM( IDM_TEXTURE_180 );
  1648.     CHECKITEM( IDM_TEXTURE_270 );
  1649. }
  1650.  
  1651. void RBSelectTextureFilter( HMENU hMenu, WPARAM wID )
  1652. {
  1653.     CHECKITEM( IDM_TEXTURE_NEAREST );
  1654.     CHECKITEM( IDM_TEXTURE_LINEAR );
  1655. }
  1656.  
  1657. void RBSelectFogCurve( HMENU hMenu, WPARAM wID )
  1658. {
  1659.     CHECKITEM( IDM_FOG_LINEAR );
  1660.     CHECKITEM( IDM_FOG_EXP );
  1661.     CHECKITEM( IDM_FOG_EXP2 );
  1662. }
  1663.  
  1664. void RBSelectTriangleSize( HMENU hMenu, WPARAM wID )
  1665. {
  1666.     CHECKITEM( IDM_SIZE_3 );
  1667.     CHECKITEM( IDM_SIZE_10 );
  1668.     CHECKITEM( IDM_SIZE_25 );
  1669.     CHECKITEM( IDM_SIZE_50 );
  1670.     CHECKITEM( IDM_SIZE_100 );
  1671.     CHECKITEM( IDM_SIZE_1000 );
  1672.     CHECKITEM( IDM_SIZE_10000 );
  1673. }
  1674.  
  1675. void RBSelectZoom( HMENU hMenu, WPARAM wID )
  1676. {
  1677.     CHECKITEM( IDM_ZOOM_1x1 );
  1678.     CHECKITEM( IDM_ZOOM_1x2 );
  1679.     CHECKITEM( IDM_ZOOM_1x4 );
  1680.     CHECKITEM( IDM_ZOOM_1x8 );
  1681. }
  1682.  
  1683. void RBDoClearTest( HWND hWnd )
  1684. {
  1685.     glClear( GL_COLOR_BUFFER_BIT );
  1686. }
  1687.  
  1688. void RBDoHatTest( HWND hWnd )
  1689. {
  1690.     int i, j;
  1691.  
  1692.     glBegin( GL_TRIANGLES );
  1693.     for ( j = 0; j < s_elements_data.num_element_rows; j++ )
  1694.     {
  1695.         for ( i = 0; i < s_elements_data.verts_per_row-2; i++ )
  1696.         {
  1697.             if ( s_config.do_texture )
  1698.                 glTexCoord2fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i]].st );
  1699.             glColor3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i]].rgb );
  1700.             glVertex3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i]].xyz );
  1701.  
  1702.             if ( s_config.do_texture )
  1703.                 glTexCoord2fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i+1]].st );
  1704.             glColor3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i+1]].rgb );
  1705.             glVertex3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i+1]].xyz );
  1706.  
  1707.             if ( s_config.do_texture )
  1708.                 glTexCoord2fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i+2]].st );
  1709.             glColor3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i+2]].rgb );
  1710.             glVertex3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i+2]].xyz );
  1711.         }
  1712.     }
  1713.     glEnd();
  1714. }
  1715.  
  1716. void RBDoHatStripTest( HWND hWnd )
  1717. {
  1718.     int i, j;
  1719.  
  1720.     for ( j = 0; j < s_elements_data.num_element_rows; j++ )
  1721.     {
  1722.         glBegin( GL_TRIANGLE_STRIP );
  1723.         for ( i = 0; i < s_elements_data.verts_per_row; i++ )
  1724.         {
  1725.             if ( s_config.do_texture )
  1726.                 glTexCoord2fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i]].st );
  1727.             glColor3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i]].rgb );
  1728.             glVertex3fv( s_elements_data.interleaved_array[s_elements_data.elements_array[j][i]].xyz );
  1729.         }
  1730.         glEnd();
  1731.     }
  1732. }
  1733.  
  1734. void RBDoHatDrawElementsTest( HWND hWnd )
  1735. {
  1736.     int i;
  1737.  
  1738.     glInterleavedArrays( GL_T2F_C3F_V3F, 0, s_elements_data.interleaved_array );
  1739.  
  1740.     for ( i = 0; i < s_elements_data.num_element_rows; i++ )
  1741.     {
  1742.         glDrawElements( GL_TRIANGLE_STRIP, s_elements_data.verts_per_row, GL_UNSIGNED_INT, s_elements_data.elements_array[i] );
  1743.     }
  1744. }
  1745.  
  1746. void RBDoTest( HWND hWnd )
  1747. {
  1748.     int i;
  1749.     DWORD start, stop;
  1750.     unsigned long total = 0L;
  1751.     
  1752.     glColor3f( 1.0F, 0.0F, 0.0F );
  1753.     
  1754.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  1755.     glFinish();
  1756.  
  1757.     for ( i = 0; i < s_config.iterations; i++ )
  1758.     {
  1759.         start = timeGetTime();
  1760.         
  1761.         if ( s_config.primitive == IDM_TRIANGLES )
  1762.         {
  1763.             RBDoHatTest( hWnd );
  1764.         }
  1765.         else if ( s_config.primitive == IDM_TRIANGLE_STRIP )
  1766.         {
  1767.             RBDoHatStripTest( hWnd );
  1768.         }
  1769.         else if ( s_config.primitive == IDM_DRAW_ELEMENTS )
  1770.         {
  1771.             RBDoHatDrawElementsTest( hWnd );
  1772.         }
  1773.         else
  1774.         {
  1775.             RBDoClearTest( hWnd );
  1776.         }
  1777.         
  1778.         glFinish();
  1779.  
  1780.         stop = timeGetTime();
  1781.         
  1782.         s_stats.area_filled        += ( float ) ( s_stats.num_screen_triangles * s_config.triangle_size );
  1783.         s_stats.triangles_rendered += s_stats.num_screen_triangles;
  1784.  
  1785.         total += ( stop - start );
  1786.     }
  1787.     
  1788.     s_stats.elapsed_time = total / 1000.0F;
  1789.  
  1790.     if ( s_config.primitive == IDM_CLEAR )
  1791.     {
  1792.         RECT r;
  1793.         float screen_size, total_rendered;
  1794.         
  1795.         GetClientRect( hWnd, &r );
  1796.         
  1797.         screen_size = ( float ) r.right * ( float ) r.bottom;
  1798.         total_rendered = screen_size * s_config.iterations;
  1799.         
  1800.         s_stats.mpixels_second = total_rendered / ( s_stats.elapsed_time * 1000000.0F );
  1801.     }
  1802.     else
  1803.     {
  1804.         s_stats.triangles_second = ( ( float ) s_stats.triangles_rendered ) / s_stats.elapsed_time;
  1805.         s_stats.mpixels_second   = ( ( float ) ( s_stats.area_filled ) ) / ( 1000000.0F * ( s_stats.elapsed_time ) ) ;
  1806.     }
  1807. }
  1808.  
  1809. void RBLogDialog( HINSTANCE hInstance )
  1810. {
  1811.     DialogBox( hInstance, MAKEINTRESOURCE( IDD_STATS_DIALOG ), 0, StatsDialogProc );
  1812. }
  1813.  
  1814. BOOL CALLBACK StatsDialogProc( HWND hDlg,
  1815.                               UINT uMsg,
  1816.                               WPARAM wParam,
  1817.                               LPARAM lParam )
  1818. {
  1819.     char buffer[4096];
  1820.     
  1821.     switch( uMsg )
  1822.     {
  1823.     case WM_INITDIALOG:
  1824.         {
  1825.             sprintf( buffer, "\n"
  1826.                 "  Triangle size:\t\t%d\n"
  1827.                 "\n"
  1828.                 "  Triangles/second:\t%.0f\n"
  1829.                 "  Mpixels/second:\t%f\n"
  1830.                 "\n"
  1831.                 "",
  1832.                 s_config.triangle_size,
  1833.                 s_stats.triangles_second, 
  1834.                 s_stats.mpixels_second );
  1835.             SetDlgItemText( hDlg, IDC_STATS, buffer );
  1836.         }
  1837.         return TRUE;
  1838.     case WM_COMMAND:
  1839.         if ( wParam == IDOK )
  1840.         {
  1841.             EndDialog( hDlg, RB_OK );
  1842.             return TRUE;
  1843.         }
  1844.         break;
  1845.     }
  1846.     
  1847.     return FALSE;
  1848. }
  1849.  
  1850. void RBGenerateLog( const char *logfilename )
  1851. {
  1852.     time_t      t;
  1853.     const char *enable_string[] = { "disabled", "enabled" };
  1854.     const char *datestring;
  1855.     FILE       *fp = 0;
  1856.     
  1857.     const char *depthfunc[] =
  1858.     {
  1859.         "GL_NEVER",
  1860.             "GL_LESS",
  1861.             "GL_EQUAL",
  1862.             "GL_LEQUAL",
  1863.             "GL_GREATER",
  1864.             "GL_NOTEQUAL",
  1865.             "GL_GEQUAL",
  1866.             "GL_ALWAYS"
  1867.     };
  1868.     
  1869.     const char *drawbuffer[] =
  1870.     {
  1871.         "GL_FRONT",
  1872.             "GL_BACK"
  1873.     };
  1874.     
  1875.     const char *perspective[] =
  1876.     {
  1877.         "GL_FASTEST",
  1878.             "GL_NICEST"
  1879.     };
  1880.     
  1881.     const char *fogcurve;
  1882.     const char *texenv, *texfilter;
  1883.     
  1884.     switch ( s_config.fog_curve )
  1885.     {
  1886.     case GL_LINEAR:
  1887.         fogcurve = "GL_LINEAR";
  1888.         break;
  1889.     case GL_EXP:
  1890.         fogcurve = "GL_EXP";
  1891.         break;
  1892.     case GL_EXP2:
  1893.         fogcurve = "GL_EXP2";
  1894.         break;
  1895.     default:
  1896.         fogcurve = "(unknown)";
  1897.         break;
  1898.     };
  1899.     
  1900.     switch ( s_config.texture_environment )
  1901.     {
  1902.     case GL_REPLACE:
  1903.         texenv = "GL_REPLACE";
  1904.         break;
  1905.     case GL_DECAL:
  1906.         texenv = "GL_DECAL";
  1907.         break;
  1908.     case GL_MODULATE:
  1909.         texenv = "GL_MODULATE";
  1910.         break;
  1911.     case GL_ADD:
  1912.         texenv = "GL_ADD";
  1913.         break;
  1914.     default:
  1915.         texenv = "(unknown)";
  1916.         break;
  1917.     }
  1918.  
  1919. #ifdef NOTYET    
  1920.     switch ( s_config.texture_format )
  1921.     {
  1922.     case IDM_TEXTURE_CI:
  1923.         texfmt = "color-index";
  1924.         break;
  1925.     case IDM_TEXTURE_RGB:
  1926.         texfmt = "RGB";
  1927.         break;
  1928.     default:
  1929.         texfmt = "(unknown)";
  1930.         break;
  1931.     }
  1932. #endif
  1933.     
  1934.     switch ( s_config.texture_filter )
  1935.     {
  1936.     case IDM_TEXTURE_NEAREST:
  1937.         texfilter = "color-index";
  1938.         break;
  1939.     case IDM_TEXTURE_LINEAR:
  1940.         texfilter = "RGB";
  1941.         break;
  1942.     default:
  1943.         texfilter = "(unknown)";
  1944.         break;
  1945.     }
  1946.     
  1947.     if ( ( fp = fopen( logfilename, "a+" ) ) != 0 )
  1948.     {
  1949.         time( &t );
  1950.         datestring = ctime( &t );
  1951.         
  1952.         fprintf( fp, "\n/*--- %-20.20s ---------------------------------------------------------- */\n\n", datestring );
  1953.         fprintf( fp, "OEM:               %s\n", glGetString( GL_VENDOR ) );
  1954.         fprintf( fp, "Version:           %s\n", glGetString( GL_VERSION ) );
  1955.         fprintf( fp, "Renderer:          %s\n", glGetString( GL_RENDERER ) );
  1956.         fprintf( fp, "\n" );
  1957.         fprintf( fp, "Triangle size:     %d\n", s_config.triangle_size );
  1958.         fprintf( fp, "Dither:            %s\n", enable_string[s_config.do_dither] );
  1959.         fprintf( fp, "Draw buffer:       %s\n", drawbuffer[s_config.draw_buffer - GL_FRONT] );
  1960.         fprintf( fp, "\n" );
  1961.         fprintf( fp, "Depth buffer:      %s\n", enable_string[s_config.do_depth_test] );
  1962.         fprintf( fp, "Depth size:        %d-bit\n", s_config.depth_size );
  1963.         fprintf( fp, "Depth writes:      %s\n", enable_string[s_config.do_depth_writes] );
  1964.         fprintf( fp, "Depth test:        %s\n", depthfunc[s_config.depth_func - GL_NEVER] );
  1965.         fprintf( fp, "Depth clear:       %f\n", s_config.depth_clear );
  1966.         fprintf( fp, "\n" );
  1967.         fprintf( fp, "Fog:               %s\n", enable_string[s_config.do_fog] );
  1968.         fprintf( fp, "Cheap fog:         %s\n", enable_string[s_config.do_cheap_fog] );
  1969.         fprintf( fp, "Fog curve:         %s\n", fogcurve );
  1970.         fprintf( fp, "\n" );
  1971.         fprintf( fp, "Texturing:         %s\n", enable_string[s_config.do_texture] );
  1972.         fprintf( fp, "Env:               %s\n", texenv );
  1973.         fprintf( fp, "Width:             %d\n", s_config.texture_width );
  1974.         fprintf( fp, "Height:            %d\n", s_config.texture_height );
  1975.         fprintf( fp, "Orientation:       %d\n", s_config.texture_orientation );
  1976.         fprintf( fp, "Perspective:       %s\n", perspective[s_config.perspective_correction - GL_FASTEST] );
  1977.         fprintf( fp, "Filter:            %s\n", texfilter );
  1978.         fprintf( fp, "\n" );
  1979.         fprintf( fp, "Iterations:        %d\n",   s_config.iterations );
  1980.         fprintf( fp, "Triangles/second:  %.0f\n", s_stats.triangles_second );
  1981.         fprintf( fp, "Mpixels/second:    %f\n",   s_stats.mpixels_second );
  1982.         
  1983.         fclose( fp );
  1984.     }
  1985. }
  1986.  
  1987. void RBStoreConfigToDisk( void )
  1988. {
  1989.     FILE *fp;
  1990.     
  1991.     if ( ( fp = fopen( CFGNAME, "wb" ) ) != 0 )
  1992.     {
  1993.         fwrite( &s_config, sizeof( s_config ), 1, fp );
  1994.         fclose( fp );
  1995.     }
  1996. }
  1997.  
  1998. void RBCreateTexture( void )
  1999. {
  2000.     int num_components;
  2001.     int format;
  2002.     GLubyte *data;
  2003.     int      s, t;
  2004.     
  2005.     if ( s_config.rgb_mode )
  2006.     {
  2007.         num_components = 3;
  2008.         format         = GL_RGB;
  2009.         
  2010.         data = malloc( sizeof( unsigned char ) * 4 * s_config.texture_width * s_config.texture_height );
  2011.  
  2012.         if ( s_config.random_texture )
  2013.             srand( 0 );
  2014.         
  2015.         for ( t = 0; t < s_config.texture_height; t++ )
  2016.         {
  2017.             for ( s = 0; s < s_config.texture_width; s++ )
  2018.             {
  2019.                 if ( s_config.random_texture )
  2020.                 {
  2021.                     data[(t*s_config.texture_width+s)*3+0] = rand() * 255 / RAND_MAX;
  2022.                     data[(t*s_config.texture_width+s)*3+1] = rand() * 255 / RAND_MAX;
  2023.                     data[(t*s_config.texture_width+s)*3+2] = rand() * 255 / RAND_MAX;
  2024.                 }
  2025.                 else
  2026.                 {
  2027.                     if ( ( s + t ) & 1 )
  2028.                     {
  2029.                         data[(t*s_config.texture_width+s)*3+0] = 0xFF;
  2030.                         data[(t*s_config.texture_width+s)*3+1] = 0xFF;
  2031.                         data[(t*s_config.texture_width+s)*3+2] = 0xFF;
  2032.                     }  
  2033.                     else
  2034.                     {
  2035.                         data[(t*s_config.texture_width+s)*3+0] = 0x00;
  2036.                         data[(t*s_config.texture_width+s)*3+1] = 0x00;
  2037.                         data[(t*s_config.texture_width+s)*3+2] = 0x00;
  2038.                     }
  2039.                 }
  2040.             }
  2041.         }
  2042.         
  2043.     }
  2044.     else
  2045.     {
  2046.         num_components = GL_COLOR_INDEX8_EXT;
  2047.         format         = GL_COLOR_INDEX;
  2048.         
  2049.         data = malloc( sizeof( char ) * s_config.texture_width * s_config.texture_height );
  2050.         
  2051.         for ( t = 0; t < s_config.texture_height; t++ )
  2052.         {
  2053.             for ( s = 0; s < s_config.texture_width; s++ )
  2054.             {
  2055.                 if ( s_config.random_texture )
  2056.                 {
  2057.                     data[t*s_config.texture_width+s] = rand() * 255 / RAND_MAX;
  2058.                 }
  2059.                 else
  2060.                 {
  2061.                     if ( ( s + t ) & 1 )
  2062.                     {
  2063.                         data[t*s_config.texture_width+s] = 0xFF;
  2064.                     }  
  2065.                     else
  2066.                     {
  2067.                         data[t*s_config.texture_width+s] = 0x00;
  2068.                     }
  2069.                 }
  2070.             }
  2071.         }
  2072.     }
  2073.     
  2074.     glTexImage2D( GL_TEXTURE_2D,
  2075.         0,                           // base level
  2076.         num_components,              // number of color components in the texture
  2077.         s_config.texture_width,
  2078.         s_config.texture_height,
  2079.         0,                           // border
  2080.         format,                      // texture format
  2081.         GL_UNSIGNED_BYTE,            // texture type
  2082.         data );
  2083.     
  2084.     free( data );
  2085. }
  2086.  
  2087. void RbMessage( int type, const char *msg )
  2088. {
  2089.     switch ( type )
  2090.     {
  2091.     case RB_MSG_ERROR:
  2092.         MessageBox( 0, msg, "RB Error", MB_OK | MB_ICONERROR );
  2093.         break;
  2094.     case RB_MSG_WARNING:
  2095.         MessageBox( 0, msg, "RB Warning", MB_OK | MB_ICONWARNING );
  2096.         break;
  2097.     case RB_MSG_INFORMATION:
  2098.     default:
  2099.         MessageBox( 0, msg, "RB Information", MB_OK | MB_ICONINFORMATION );
  2100.         break;
  2101.     }
  2102. }
  2103.  
  2104. static void RBHelp( void )
  2105. {
  2106.    char superbuffer[1000]=
  2107.       "-?\t\tthis help screen\n"
  2108.       "-noprompt\t\tdon't prompt when done\n"
  2109.       "-everything\trun full test suite\n"
  2110.       "-checkerboard\tuse a checkerboard texture (not recommended)\n"
  2111.       "-lockarrays\t\tuse SGI lock arrays extension\n"
  2112.       "-width:val\t\tspecify the window size in pixels (default is 640)\n"
  2113.       "-height:val\t\tspecify the window height in pixels (default is 480)\n\n";
  2114.  
  2115.    MessageBox( 0, superbuffer, "RasterBench 1.00, Copyright (C) 1997 Silicon Graphics, Inc.", MB_OK | MB_ICONINFORMATION );
  2116. }
  2117.  
  2118. #define MARGIN 10
  2119.  
  2120. void RBBuildData( HWND hWnd )
  2121. {
  2122. #if PRINTELEMENTS
  2123.     FILE *fp = fopen( "debug.out", "wt" );
  2124. #endif
  2125.     float twidth, theight;
  2126.     RECT  rect;
  2127.     int   r, c;
  2128.     float z = -0.9F;
  2129.     float s_scale = 1.0F / ( s_config.ftexture_width * s_config.texture_zoom );
  2130.     float t_scale = 1.0F / ( s_config.ftexture_height * s_config.texture_zoom );
  2131.  
  2132.     /*
  2133.     ** get information on the client rectangle
  2134.     */
  2135.     GetClientRect( hWnd, &rect );
  2136.     twidth = ( float ) sqrt( 2*s_config.triangle_size );
  2137.     theight = twidth;
  2138.  
  2139.     /*
  2140.     ** compute vertex grid
  2141.     */
  2142.     s_elements_data.num_vertex_rows = ( int ) ( ( float ) ( rect.bottom  - ( 2.0F * MARGIN ) ) / ( theight * 2.0F ) );
  2143.     s_elements_data.num_cols        = ( int ) ( ( float ) ( rect.right   - ( 2.0F * MARGIN ) ) / twidth );
  2144.  
  2145.     s_elements_data.num_vertex_rows -= 1;
  2146.     s_elements_data.num_vertex_rows |= 1;
  2147.  
  2148.     s_elements_data.verts_per_row = s_elements_data.num_cols + 1 + s_elements_data.num_cols;
  2149.  
  2150.     s_elements_data.num_vertices = s_elements_data.num_vertex_rows * s_elements_data.verts_per_row;
  2151.  
  2152.     s_elements_data.interleaved_array = ( RBIVertex * ) malloc( sizeof( RBIVertex ) * s_elements_data.num_vertices );
  2153.  
  2154.     for ( r = 0; r < s_elements_data.num_vertex_rows; r++ )
  2155.     {
  2156.         RBIVertex *rowptr = &s_elements_data.interleaved_array[r*s_elements_data.verts_per_row];
  2157.  
  2158.         for ( c = 0; c < s_elements_data.num_cols+1; c++ )
  2159.         {
  2160.             rowptr->xyz[0] = MARGIN + c * twidth;
  2161.             rowptr->xyz[1] = MARGIN + r * theight * 2.0F;
  2162.             rowptr->xyz[2] = z;
  2163.  
  2164.             rowptr->st[0] = s_scale * rowptr->xyz[0];
  2165.             rowptr->st[1] = t_scale * rowptr->xyz[1];
  2166.  
  2167.             if ( c % 3 == 0 )
  2168.             {
  2169.                 rowptr->rgb[0] = 1.0F;
  2170.                 rowptr->rgb[1] = 0.0F;
  2171.                 rowptr->rgb[2] = 0.0F;
  2172.             }
  2173.             else if ( c % 3 == 1 )
  2174.             {
  2175.                 rowptr->rgb[0] = 0.0F;
  2176.                 rowptr->rgb[1] = 1.0F;
  2177.                 rowptr->rgb[2] = 0.0F;
  2178.  
  2179.             }
  2180.             else
  2181.             {
  2182.                 rowptr->rgb[0] = 0.0F;
  2183.                 rowptr->rgb[1] = 0.0F;
  2184.                 rowptr->rgb[2] = 1.0F;
  2185.             }
  2186.  
  2187.             rowptr++;
  2188.         }
  2189.  
  2190.         for ( c = 0; c < s_elements_data.num_cols; c++ )
  2191.         {
  2192.             rowptr->xyz[0] = MARGIN + c * twidth  + twidth  * 0.5F;
  2193.             rowptr->xyz[1] = MARGIN + r * theight * 2.0F + theight;
  2194.             rowptr->xyz[2] = z;
  2195.  
  2196.             rowptr->st[0] = s_scale * rowptr->xyz[0];
  2197.             rowptr->st[1] = t_scale * rowptr->xyz[1];
  2198.  
  2199.             if ( c % 3 == 1 )
  2200.             {
  2201.                 rowptr->rgb[0] = 1.0F;
  2202.                 rowptr->rgb[1] = 0.0F;
  2203.                 rowptr->rgb[2] = 0.0F;
  2204.             }
  2205.             else if ( c % 3 == 2 )
  2206.             {
  2207.                 rowptr->rgb[0] = 0.0F;
  2208.                 rowptr->rgb[1] = 1.0F;
  2209.                 rowptr->rgb[2] = 0.0F;
  2210.             }
  2211.             else
  2212.             {
  2213.                 rowptr->rgb[0] = 0.0F;
  2214.                 rowptr->rgb[1] = 0.0F;
  2215.                 rowptr->rgb[2] = 1.0F;
  2216.             }
  2217.  
  2218.             rowptr++;
  2219.         }
  2220.     }
  2221.  
  2222.     /*
  2223.     ** compute elements
  2224.     */
  2225.     s_elements_data.num_element_rows = s_elements_data.num_vertex_rows + s_elements_data.num_vertex_rows - 1;
  2226.     s_elements_data.elements_array = ( unsigned int ** ) malloc( sizeof( unsigned int * ) * s_elements_data.num_element_rows );
  2227.     for ( r = 0; r < s_elements_data.num_element_rows; r++ )
  2228.     {
  2229. #if PRINTELEMENTS
  2230.         fprintf( fp, "row %d\n", r );
  2231. #endif
  2232.  
  2233.         s_elements_data.elements_array[r] = ( unsigned int * ) malloc( sizeof( unsigned int ) * s_elements_data.verts_per_row );
  2234.  
  2235.         /*
  2236.         ** wide bottom row
  2237.         */
  2238.         if ( !( r & 1 ) )
  2239.         {
  2240.             for ( c = 0; c < s_elements_data.verts_per_row; c++ )
  2241.             {
  2242.                 if ( !( c & 1 ) )
  2243.                 {
  2244.                     s_elements_data.elements_array[r][c] = r * ( s_elements_data.verts_per_row ) + ( c - r * s_elements_data.verts_per_row ) /2;
  2245.                 }
  2246.                 else
  2247.                 {
  2248.                     s_elements_data.elements_array[r][c] = s_elements_data.elements_array[r][c-1] + s_elements_data.num_cols + 1;
  2249.                 }
  2250.             }
  2251.         }
  2252.         /*
  2253.         ** narrow bottom row
  2254.         */
  2255.         else
  2256.         {
  2257.             for ( c = 0; c < s_elements_data.verts_per_row; c++ )
  2258.             {
  2259.                 if ( !( c & 1 ) )
  2260.                 {
  2261.                     s_elements_data.elements_array[r][c] = r * ( s_elements_data.verts_per_row ) + ( c - r * s_elements_data.verts_per_row ) / 2 + s_elements_data.num_cols;
  2262.                 }
  2263.                 else
  2264.                 {
  2265.                     s_elements_data.elements_array[r][c] = s_elements_data.elements_array[r][c-1] - s_elements_data.num_cols;
  2266.                 }
  2267.             }
  2268.         }
  2269.  
  2270. #if PRINTELEMENTS
  2271.         for ( c = 0; c < s_elements_data.verts_per_row; c++ )
  2272.         {
  2273.             fprintf( fp, "%d: %.2f,%.2f,%.2f\n", 
  2274.                      s_elements_data.elements_array[r][c],
  2275.                      s_elements_data.interleaved_array[s_elements_data.elements_array[r][c]].xyz[0],
  2276.                      s_elements_data.interleaved_array[s_elements_data.elements_array[r][c]].xyz[1],
  2277.                      s_elements_data.interleaved_array[s_elements_data.elements_array[r][c]].xyz[2] );
  2278.         }
  2279. #endif
  2280.     }
  2281.  
  2282.     s_stats.num_screen_triangles = s_elements_data.num_element_rows * ( s_elements_data.num_cols * 2 - 1 );
  2283.  
  2284. #if PRINTELEMENTS
  2285.     fclose( fp );
  2286. #endif
  2287. }
  2288.